package com.thirteen.app.service.impl;

import com.google.common.base.Joiner;
import com.thirteen.app.daoTest.*;
import com.thirteen.app.dto.CreateExamRequest.ExamDto;
import com.thirteen.app.dto.ExamConditionDto;
import com.thirteen.app.dto.ExamRecordResponse.SelectExamByNameDto;
import com.thirteen.app.dto.ExamRecordResponse.UnJudgedDto;
import com.thirteen.app.dto.ExamResponse.ExamListStudentDto;
import com.thirteen.app.dto.ExamResponse.ExamListTeacherDto;
import com.thirteen.app.dto.ExamResponse.SelectByIdDto;
import com.thirteen.app.dto.ExamResponse.SelectExamByUserDto;
import com.thirteen.app.dto.PaperList;
import com.thirteen.app.dto.PaperRespose.PaperDto;
import com.thirteen.app.dto.PaperRespose.QuestionDto;
import com.thirteen.app.dto.PaperRespose.QuestionTypeDto;
import com.thirteen.app.entity.Answer;
import com.thirteen.app.entity.Exam;
import com.thirteen.app.entity.Question;
import com.thirteen.app.entity.QuestionType;
import com.thirteen.app.service.ExamRecordService;
import com.thirteen.app.service.ExamService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

@Service("examService")
public class ExamServiceImpl implements ExamService {

    @Resource
    private ExamDao examDao;

    @Resource
    private ExamRecordDao examRecordDao;

    @Resource
    private QuestionTypeDao questionTypeDao;

    @Resource
    private QuestionDao questionDao;

    @Resource
    private AnswerDao answerDao;

    @Resource
    private PaperObjectiveDao paperObjectiveDao;

    @Resource
    private PaperSubjectiveDao paperSubjectiveDao;

    @Resource
    private ExamRecordService examRecordService;

    @Resource
    private UserExamDao userExamDao;

    @Resource
    private PaperDao paperDao;

    @Resource
    private QuestionTypeQuestionDao questionTypeQuestionDao;

    //    开始考试
    public Integer startExam(Integer examId, Integer userId) {
        Integer state = examRecordDao.queryState(examId, userId);
        if (state == 0) {
            examRecordService.insertRecord(examId, userId);
            Integer examRecordId = examRecordDao.queryExamRecordId(examId, userId);
            Exam exam = examDao.queryById(examId);
            Integer paperId = exam.getPaperId();
            List<QuestionType> questionTypes;
            List<Question> questions;
            List<Answer> answers;
            questionTypes = questionTypeDao.queryQuestionType(paperId);
            for (QuestionType i : questionTypes) {
                questions = questionDao.queryQuestion(i.getQuestionTypeId());
                for (Question j : questions) {
                    answers = answerDao.querySelection(j.getQuestionId());
                    for (Answer k : answers) {
                        if (j.getQuestionType() < 4) {
                            paperObjectiveDao.insertObjective(examRecordId, k);
                        } else if (j.getQuestionType() == 4) {
                            paperSubjectiveDao.insertSubjectiveCompletion(examRecordId, k, j.getAnswerCount());
                        } else if (j.getQuestionType() == 5) {
                            paperSubjectiveDao.insertSubjectiveShort(examRecordId, k);
                        }
                    }
                }
            }
            return examRecordId;
        } else if (state == 1) {
            Integer examRecordId = examRecordDao.queryExamRecordId(examId, userId);
            return examRecordId;
        } else {
            return -1;
        }
    }

    @Override
    public Boolean insertExam(ExamDto examDto) {
        examDao.insertExam(examDto);
        return userExamDao.insertUserExam(examDto.getUserIdList(), examDto.getExamId());
    }

    public List<ExamListStudentDto> queryAllExamStudent(ExamConditionDto examConditionDto) {
        List<ExamListStudentDto> examListStudentDtoList = examDao.queryAllExamStudent(examConditionDto);
        for (ExamListStudentDto i : examListStudentDtoList) {
            Integer currentTryCount = examRecordDao.queryTryCount(i.getExamId(), examConditionDto.getUserId());
            if (currentTryCount == null) {
                currentTryCount = 0;
            }
            i.setRemainCount(i.getMaxTryCount() - currentTryCount);
        }
        return examListStudentDtoList;
    }

    public List<ExamListTeacherDto> queryAllExamTeacher(ExamConditionDto examConditionDto) {
        List<ExamListTeacherDto> examListTeacherDtoList = examDao.queryAllExamTeacher(examConditionDto);
        for (ExamListTeacherDto i : examListTeacherDtoList) {
            i.setTotalTime(i.getTotalTime());
            i.setUserCount(examRecordDao.queryExamUserCount(i.getExamId()));
        }
        return examListTeacherDtoList;
    }

    //zql&ar
    @Override
    public PaperList getExamPaperList(Integer examId) {
        return examDao.getExamPaperList(examId);
    }

    //wc

    @Override
    public Exam queryById(Integer examid) {
        return this.examDao.queryById(examid);
    }

    /**
     * 查询多条数据
     */
    @Override
    public Map<String, Object> queryAllByLimit(int offset, int limit) {
        Map<String, Object> map = new HashMap<>();
        map.put("data", this.examDao.queryAllByLimit((offset - 1) * offset, limit));
        map.put("count", examDao.getExamCount());
        return map;
    }

    /**
     * 修改数据
     */
    @Override
    public boolean update(Exam exam) {
        return this.examDao.update(exam) > 0;
    }

    /**
     * 通过主键删除数据
     */
    @Override
    public boolean deleteById(Integer examid) {
        return this.examDao.deleteById(examid) > 0;
    }

    @Override
    public int getExamCount() {
        return this.examDao.getExamCount();
    }

    @Override
    public Map<String, Object> queryAllByTeacherTime(String beginTime, String endTime, String examName, Integer userId) {
        List<SelectByIdDto> list = new LinkedList<>();
        list = this.examDao.queryAllByTeacherTime(beginTime, endTime, examName, userId);
        Map<String, Object> map = new HashMap<>();
        map.put("data", list);
        map.put("count", list.size());
        return map;
    }

    @Override
    public Map<String, Object> queryExamByName(String examName, Integer userId) {
        List<SelectExamByNameDto> list = examDao.selectExamByName(examName);
        List<SelectExamByNameDto> resultList = new LinkedList<>();
        for (SelectExamByNameDto exam : list) {
            List<UnJudgedDto> judgeDTOList = new LinkedList<>();
            judgeDTOList = examRecordDao.queryAllUnJudgeByExamId(exam.getExamId());
            if (judgeDTOList.isEmpty()) {
                exam.setJudged(true);
            } else
                exam.setJudged(false);
            exam.setUserCount(examDao.selectUserCountByExamName(exam.getTitle()));
            if (exam.getUserId() == userId)
                resultList.add(exam);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("data", resultList);
        map.put("count", resultList.size());

        return map;
    }

    @Override
    public boolean queryExamState(Integer examId, Integer userId) {
        if (this.examRecordDao.queryState(examId, userId) == 1)
            return false;
        else
            return true;
    }

    @Override
    public PaperDto getPaper(Integer examId, Integer examRecordId, Integer userId) {
        //获取试卷中的客观题Id
        List<Integer> obList = this.examRecordDao.getQuestionIdFromObjective(examRecordId);
        //获取试卷中的主观题Id
        List<Integer> subList = this.examRecordDao.getQuestionIdFromSubjective(examRecordId);
        //将所有题目Id合到一起
        obList.addAll(subList);

        List<QuestionTypeDto> questiontypelist = new LinkedList<>();
        //根据examId获取paperId，再通过paperId获得题型Id的list列表
        questiontypelist = this.questionTypeDao.queryAllByExamId(examId);

        PaperDto paperDTO = paperDao.queryByExamId(examId, userId);
        //将小题加入到对应的题型的题目列表中
        for (QuestionTypeDto questiontypedto : questiontypelist
        ) {
            //存储每一个大题中的小题
            List<QuestionDto> questionDTOList = new LinkedList<>();
            //存储每一个大题中随机是个小题的ID
            List<Integer> questionIdList = new LinkedList<>();
            for (Integer questionId : obList
            ) {
                //如果小题对应的题型与大题提醒一致，就将小题Id加入其中
                if (questiontypedto.getQuestionTypeId() == this.questionTypeDao.queryQuestionTypeID(questionId)) {
                    questionIdList.add(questionId);
                }
            }

            //根据ListId找到对应的十个题目
            questionDTOList = questionDao.queryByListId(questionIdList);
            //将每一个小题的答案加入其中
            for (QuestionDto questiondto : questionDTOList
            ) {
                questiondto.setChoicesList(answerDao.queryByQuestionId(questiondto.getQuestionId()));
                List<String> answeredList = new LinkedList<>();
                answeredList = answerDao.queryHasAnswered(examRecordId, questiondto.getQuestionId());
                String answer;
                if (answeredList.size() == 0)
                    answer = "";
                else
                    answer = Joiner.on(",").join(answeredList);
                questiondto.setAnswer(answer);
            }
            questiontypedto.setQuestionsList(questionDTOList);
        }
        paperDTO.setPaperQuestionTypesList(questiontypelist);
        return paperDTO;

    }

//    @Override
//    public PaperDto paperConstituteRandom(Integer examId, Integer userId) {
//        List<QuestionTypeDto> questiontypelist = new LinkedList<>();
//        //根据examId获取paperId，再通过paperId获得题型Id的list列表
//        questiontypelist = this.questionTypeDao.queryAllByExamId(examId);
//        //paperDTO为存储整个卷子的所有题
//        PaperDto paperDTO = paperDao.queryByExamId(examId, userId);
//
//        for (QuestionTypeDto questiontypedto : questiontypelist
//        ) {
//            //存储每一个大题中的小题
//            List<QuestionDto> questionDTOList = new LinkedList<>();
//            //存储每一个大题中随机是个小题的ID
//            List<Integer> questionIdList = new LinkedList<>();
//            //根据题型ID和对应的题目数量进行随机选取题目，返回一个题目ID列表
//            questionIdList = questionTypeQuestionDao.selectRandom(questiontypedto.getQuestionTypeId(), questiontypedto.getQuestionCount());
//
//            //根据ListId找到对应的十个题目
//            questionDTOList = questionDao.queryByListId(questionIdList);
//            for (QuestionDto questiondto : questionDTOList
//            ) {
//                questiondto.setChoicesList(answerDao.queryByQuestionId(questiondto.getQuestionId()));
//            }
//            questiontypedto.setQuestionsList(questionDTOList);
//        }
//        paperDTO.setPaperQuestionTypesList(questiontypelist);
//        return paperDTO;
//    }

    @Override
    public Map<String, Object> queryAllByTime(String beginTime, String endTime, String examName, Integer userId) {
        List<SelectByIdDto> list = new LinkedList<>();
        list = this.examDao.queryAllByTime(beginTime, endTime, examName, userId);
        for (SelectByIdDto selectallexamdto : list
        ) {
            int tryCount;
            if (this.examDao.queryTryCount(selectallexamdto.getExamId(), userId) == null)
                tryCount = 0;
            else
                tryCount = this.examDao.queryTryCount(selectallexamdto.getExamId(), userId);
            selectallexamdto.setRemainCount(selectallexamdto.getMaxTryCount() - tryCount);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("data", list);
        map.put("count", list.size());
        return map;
    }

    @Override
    public List<SelectExamByUserDto> queryAllByUser(ExamConditionDto examConditionDto) {
        return this.examDao.queryAllByUser(examConditionDto);
    }

    @Override
    public String getType(Object obj) {
        return obj.getClass().getName();
    }


    public boolean isExist(String target, List<SelectExamByUserDto> list) {
        if (list.isEmpty())
            return false;
        for (SelectExamByUserDto selectexambyuserdto : list
        ) {
            if (selectexambyuserdto.getTitle().equals(target))
                return true;
        }
        return false;
    }


    @Override
    public boolean insertAnswerSet(PaperDto paperDTO, Integer examRecordId) {
        List<QuestionTypeDto> list = paperDTO.getPaperQuestionTypesList();
        for (QuestionTypeDto questionType : list
        ) {
            List<QuestionDto> questionDTOList = questionType.getQuestionsList();
            for (QuestionDto question : questionDTOList
            ) {
                List<Answer> answers = answerDao.querySelection(question.getQuestionId());
                for (Answer answer : answers) {
                    if (question.getQuestionType() < 4) {
                        paperObjectiveDao.insertObjective(examRecordId, answer);
                    } else if (question.getQuestionType() == 4) {
                        paperSubjectiveDao.insertSubjectiveCompletion(examRecordId, answer, question.getAnswerCount());
                    } else if (question.getQuestionType() == 5) {
                        paperSubjectiveDao.insertSubjectiveShort(examRecordId, answer);
                    }
                }
            }
        }
        return false;
    }


}
